// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as fs from 'fs';
import { normalize, resolve } from 'path';
import path = require('path');
import { stringify } from 'querystring';
import * as vscode from 'vscode';
import { LocalizeFile } from './LocalizeFile';
import { LocalizeItem } from './LocalizeItem';

let dicLocals: Map<string, LocalizeFile> | undefined;
let completionList: vscode.CompletionItem[] | undefined;

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

	// Use the console to output diagnostic information (console.log) and errors (console.error)
	// This line of code will only be executed once when your extension is activated
	console.log('Congratulations, your extension "LocalizeTip" is now active!');

	// The command has been defined in the package.json file
	// Now provide the implementation of the command with registerCommand
	// The commandId parameter must match the command field in package.json
	let disposable = vscode.commands.registerCommand('LocalizeTip.ReStart', () => {
		// The code you place here will be executed every time your command is executed
		// Display a message box to the user
		dicLocals = undefined
		vscode.window.showInformationMessage('LocalizeTip.ReStart!');
	});

	context.subscriptions.push(disposable);

	vscode.languages.registerHoverProvider('lua', {
		provideHover(document, position, token) {
			let folders = vscode.workspace.workspaceFolders
			if (!folders) {
				console.error("no work space");
				return new vscode.Hover('');
			}
			let word = getHoverWord(document, position, token);
			let hint = ""
			if (word.length > 0) {
				let ret = findLocal(word)
				if (ret)
					hint = ret.item.v
				else
					hint = "未定义：" + word
			}

			return new vscode.Hover(hint);
		}
	})

	vscode.languages.registerDefinitionProvider('lua', {
		provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.Definition | vscode.DefinitionLink[]>{
			let folders = vscode.workspace.workspaceFolders
			if (!folders) {
				console.error("no work space");
				return [];
			}
			let word = getHoverWord(document, position, token);
			if (word.length == 0) {
				return []
			}
			let ret = findLocal(word)
			if (!ret)
			{
				return undefined
			}
			return new vscode.Location(vscode.Uri.file(ret.filePath), new vscode.Range(ret.item.pos, ret.item.pos1))
		}
	})

	let TriggerCharacters = vscode.workspace.getConfiguration().get("LocalizeTip.TriggerCharacters", [])

	vscode.languages.registerCompletionItemProvider('lua', {
		provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem>> {
			let left = document.getText(new vscode.Range(new vscode.Position(position.line, 0), position))
			let reg = vscode.workspace.getConfiguration().get("LocalizeTip.LeftPattern", "i18n *\\( *[\"']")
			let m = left.match(new RegExp(reg));
			if (!m) 
				return undefined;

			// let strLeft = m[1]
			initLocalize()
			return completionList
			// return [
			// 	{
			// 		label: "completionTest",
			// 		kind: vscode.CompletionItemKind.Text,
			// 		detail: "completionDetail",
			// 	}
			// ]
		}
	}
	// )
		, TriggerCharacters[0]
		, TriggerCharacters[1]
		, TriggerCharacters[2]
		, TriggerCharacters[3]
		, TriggerCharacters[4]
		, TriggerCharacters[5]
		, TriggerCharacters[6]
		, TriggerCharacters[7]
		, TriggerCharacters[8]
		, TriggerCharacters[9]
	)

	vscode.workspace.onDidChangeConfiguration(
		(event) => {
			if (event.affectsConfiguration("LocalizeTip"))
			{
				console.log("onDidChangeConfiguration!!!!!!")
				clear()
			}
		}
	)

	let files = getLocalFiles()
	for (const file of files) {
		if (vscode.workspace.workspaceFolders)
		{
			for (const folder of vscode.workspace.workspaceFolders) {
				const pattern = new vscode.RelativePattern(folder, file);
				const wather = vscode.workspace.createFileSystemWatcher(pattern, false, false, false)
				wather.onDidChange(
					(e: vscode.Uri) => {
						console.log("onDidChange", e.fsPath)
						if (dicLocals) {
							updateLocal(e.fsPath)
							remakeCompletion()
						}
					}
				)
			}
		}
		
	}
}

function getHoverWord(doc: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) : string
{
	if (!doc) {
		return ""
	}
	let left = doc.getText(new vscode.Range(new vscode.Position(position.line, 0 ),  position));
	let right = doc.getText(new vscode.Range(position, new vscode.Position(position.line, 999 )));
	let reg = vscode.workspace.getConfiguration().get("LocalizeTip.LeftPattern", "i18n *\\( *[\"']")
	let m = left.match(new RegExp(reg + "(\\w+)"));
	let strLeft = "";
	if (m) {
		strLeft = m[m.length - 1];
	} else
		return "";
	let m1 = right.match(/^(\w+)/);
	let strRight = "";
	if (m1) {
		strRight = RegExp.$1;
	}
	let ret = strLeft + strRight;
	// console.log("left", left, "=", strLeft)
	// console.log("right", right, "=", strRight)
	// console.log("ret", ret)
	return ret
}

function findLocal(key: string): { item:LocalizeItem, filePath: string } | undefined
{
	initLocalize()
	if (dicLocals)
	{
		let iterator = dicLocals.keys(); 
		let r: IteratorResult<string>;   
		while (r = iterator.next(), !r.done) {
			// console.log(r.value);
			let ret = dicLocals.get(r.value)?.dicKV.get(key)
			if (ret)
				return { item: ret, filePath: r.value }
		}
	}
	return undefined
}

function initLocalize()
{
	if (!dicLocals)
	{
		dicLocals = new Map();
		completionList = [];
		let folders = vscode.workspace.workspaceFolders
		if (folders) {
			for (const folder of folders) {
				let files = getLocalFiles()
				for (const fileName of files) {
					let fileUri = vscode.Uri.joinPath(folder.uri, fileName)
					console.log("fsPath", fileUri.fsPath)
					if (!fs.existsSync(fileUri.fsPath)) {
						console.error("no work space");
						continue
					}

					// console.log(text)
					updateLocal(fileUri.fsPath)
				}
			}
		}
		remakeCompletion()
	}
}

function getLocalFiles() : string[]
{
	let files = vscode.workspace.getConfiguration().get("LocalizeTip.Files", [])
	return files
	// return ["cn.lua"];
}


function updateLocal(path:string)
{
	if (!dicLocals)
		return
	console.log("updateLocal", path)
	let localizeFile = new LocalizeFile(path)

	let text = fs.readFileSync(path).toString()
	let arr = text.split("\n")
	let strReg = vscode.workspace.getConfiguration().get("LocalizeTip.Pattern", "[ \\t]+\\[\"(\\w+)\"\\] = \"(.*)\",")
	let regexp = new RegExp(strReg)
	for (let i = 0; i < arr.length; i++) {
		const element = arr[i];
		let m = element.match(regexp)
		if (m)
		{
			let key = m[1]
			let v = m[2]
			let index = m[0].indexOf(key)
			let localizeItem = new LocalizeItem(key, v, new vscode.Position(i, index), new vscode.Position(i, index + key.length))
			localizeFile.dicKV.set(key, localizeItem)
			localizeFile.completionList?.push({
				label: key,
				detail: v,
				insertText : key
			})
			localizeFile.completionList?.push({
				label: v,
				detail: key,
				insertText : key
			})
		}
	}
	dicLocals.set(path, localizeFile)
}

function remakeCompletion()
{
	if (!completionList) {
		return
	}
	completionList.splice(0, completionList.length)
	dicLocals?.forEach((v, k) => {
		completionList = completionList?.concat(v.completionList)
	})
}

function clear()
{
	dicLocals = undefined
	completionList = undefined
}

// This method is called when your extension is deactivated
export function deactivate() {}
